<template>
    <div class="role_span">
        <div class="role_left_span">
            <table-span
                    :current-page="roleTableData.current"
                    :page-size="roleTableData.size"
                    :total="roleTableData.total"
                    :pageCount=5
                    :isShowTool="false"
                    :page-layout="roleTableData.pageLayout"
                    :current-change="roleHandleCurrentChange">
                <template v-slot:searchItem>
                    <div class="search_item_span">
                        <el-input v-model="roleSearchCondition.roleName"
                                  placeholder="请输入角色名称" clearable style="width: 140px"></el-input>
                    </div>
                    <div class="search_item_span">
                        <el-button icon="Search" size="default" type="primary" @click="searchRoleData">查询</el-button>
                    </div>
                    <div class="search_item_span">
                        <el-button icon="Plus" size="default" type="primary" :disabled="!btOption.btSaveRole"
                        @click="openRoleDialog(null,null)">新增角色</el-button>
                    </div>
                </template>
                <template v-slot:searchTable>
                    <el-table :data="roleTableData.records"
                            :highlight-current-row="false"
                            ref="roleTable"
                            height="100%"
                            @row-click="selectTableRow"
                            style="width: 100%">
                        <el-table-column
                            align="center"
                            width="50">
                            <template #default="scope">
                                <div @click="selectRoleCell(scope.row)">
                                    <div class="role_icon_span role_icon_selected" v-show="scope.row.selected">
                                        <i class="fas fa-check-square"></i>
                                    </div>
                                    <div class="role_icon_span role_icon_unselected" v-show="!scope.row.selected">
                                        <i class="far fa-square"></i>
                                    </div>
                                </div>
                            </template>
                        </el-table-column>
                        <el-table-column
                            align="center"
                            prop="roleName"
                            label="角色名称"
                            min-width="120">
                        </el-table-column>
                        <el-table-column
                            align="center"
                            label="操作"
                            width="160">
                            <template #default="scope">
                                <el-button size="small" :disabled="!btOption.btUpdateRole"
                                    @click="openRoleDialog(scope.$index, scope.row)">编辑</el-button>
                                <el-button size="small" type="danger" :disabled="!btOption.btDeleteRole"
                                    @click="roleDel(scope.$index, scope.row)">删除</el-button>
                            </template>
                        </el-table-column>
                    </el-table>
                </template>
            </table-span>
            <el-dialog
            v-model="roleDialogOption.show"
            :title="roleDialogOption.title"
            width="450px"
            :close-on-click-modal="false"
            :close-on-press-escape="false"
            :before-close="roleDialogBeforeClose"
            @close="roleDialogClose">
                <el-form
                    ref="roleFormRef"
                    :model="roleDataForm"
                    :rules="roleFormRules"
                    label-width="80px"
                    status-icon
                >
                    <el-form-item label="角色名称" prop="roleName">
                        <el-input v-model="roleDataForm.roleName" placeholder="请填写角色名称" :clearable="true"></el-input>
                    </el-form-item>
                </el-form>
                <template #footer>
                    <span class="dialog-footer">
                        <el-button @click="roleDialogBeforeClose">取消</el-button>
                        <el-button type="primary" @click="confirmRoleDialog">
                        保存
                        </el-button>
                    </span>
                </template>
            </el-dialog>
        </div>
        <div class="role_right_span">
            <el-table 
            :data="menuTableData.records"
            row-key="menuId"
            style="width: 100%;height: 100%;"
            :tree-props="{ children: 'children', hasChildren: 'hasChildren' }">
                <el-table-column
                    align="left"
                    prop="menuName"
                    label="菜单名称"
                    width="160">
                </el-table-column>
                <el-table-column
                    align="center"
                    prop="icon"
                    label="菜单图标"
                    width="80">
                    <template #default="scope">
                        <div v-html="scope.row.showIcon"></div>
                    </template>
                </el-table-column>
                <el-table-column
                    align="center"
                    prop="menuUrl"
                    label="菜单地址"
                    :show-overflow-tooltip="true"
                    min-width="120">
                </el-table-column>
                <el-table-column
                    fixed="right"
                    align="center"
                    label="操作"
                    width="90">
                    <template #default="scope">
                        <el-button size="small" type="success"
                            @click="showRequestListDialog(scope.$index, scope.row)">接口</el-button>
                    </template>
                </el-table-column>
                <el-table-column
                    fixed="right"
                    align="center"
                    label="授权"
                    width="90">
                    <template #default="scope">
                        <el-switch
                            v-model="scope.row.isAllow"
                            inline-prompt
                            active-value="1"
                            inactive-value="0"
                            active-text="是"
                            inactive-text="否"
                            style="--el-switch-on-color: #409eff; --el-switch-off-color: #f56c6c"
                            :loading="scope.row.loading"
                            :before-change="saveRoleMenu.bind(this, scope.row)"
                            :disabled="!btOption.btRoleMenuIsAllow"
                        />
                    </template>
                </el-table-column>
            </el-table>

            <!-- 接口 Dialog -->
            <el-dialog 
                width="960px"
                v-model="requestListDialogOption.isShow" 
                :title="requestListDialogOption.title"
                :close-on-press-escape="false"
                :close-on-click-modal="false"
                @open="requestListDialogOpen"
                @closed="requestListDialogClosed">
                <template #header>
                    <div class="dialog_header el-dialog__title">
                        <div>{{requestListDialogOption.title}}</div>
                        <div class="dialog_header_icon" @click="refreshReuqestDialog">
                            <el-icon class="Refresh">
                                <Refresh />
                            </el-icon>
                        </div>
                    </div>
                </template>
                <el-table
                    :data="requestListDialogOption.tableData"
                    size="default"
                    height="320"
                    max-height="420"
                    border
                    element-loading-text="加载中"
                    element-loading-spinner="el-icon-loading"
                    element-loading-background="rgba(255, 255, 255, 0.8)"
                    :show-header="true">
                    <el-table-column
                        align="center"
                        type="index"
                        width="50">
                    </el-table-column>
                    <el-table-column
                        align="left"
                        header-align="center"
                        prop="requestUrl"
                        label="请求地址"
                        min-width="220">
                    </el-table-column>                                                    
                    <el-table-column
                        align="left"
                        header-align="center"
                        prop="permissionName"
                        label="权限标识"
                        width="180">
                    </el-table-column>
                    <el-table-column
                        align="center"
                        prop="btDescribe"
                        label="描述"
                        min-width="120">
                    </el-table-column>
                    <el-table-column
                        align="center"
                        label="权限"
                        width="90">
                        <template #default="scope">
                            <el-switch
                                v-model="scope.row.isAllow"
                                inline-prompt
                                active-value="1"
                                inactive-value="0"
                                active-text="是"
                                inactive-text="否"
                                :loading="scope.row.loading"
                                style="--el-switch-on-color: #409eff; --el-switch-off-color: #f56c6c"
                                :before-change="saveRoleRequest.bind(this, scope.row)"
                                :disabled="!btOption.btRoleRequestIsAllow"
                            />
                        </template>
                    </el-table-column>
                </el-table>
            </el-dialog>
        </div>
    </div>
</template>

<script>
    import { ElMessage } from 'element-plus'
    import TableSpan from '@/components/table-span.vue';
    import { tool } from "@/js/tool.js";

    export default {
        name: "roleManage",
        data: function(){
            return {
                btOption : {
                    btSaveRole: null,
                    btUpdateRole: null,
                    btDeleteRole: null,
                    btRoleMenuIsAllow: null,
                    btRoleRequestIsAllow: null
                },
                roleSearchCondition : {
                    roleName : "",
                    page : 1,
                    size : 30
                },
                roleTableData: {
                    pageLayout: "prev, pager, next",
                    total: 0,
                    size: 30,
                    current: 1,
                    records: [],
                    selectRoleRow: null
                },
                roleDialogOption: {
                    show: false,
                    type: 0,
                    title: "",
                },
                roleFormRules: {
                    roleName: [
                        { required: true, message: '请填写角色名称', trigger: 'blur' },
                        { max: 20, message: '名称不能超过20个字符', trigger: 'blur' },
                    ]
                },
                roleDataForm: {
                    roleId: null,
                    roleName: ""
                },
                requestSearchCondition: {
                    requestName : "",
                    page : 1,
                    pageSize : 50
                },
                menuTableData: {
                    total: 0,
                    size: 30,
                    current: 1,
                    records: [],
                    selectRoleRow: null
                },
                requestListDialogOption: {
                    title: "",
                    isShow: false,
                    selectMenu: null,
                    tableData: [],
                },
            }
        },
        methods: {
            searchRoleData: function(){
                this.roleSearchCondition.page = 1;
                getRoleList(this,this.roleSearchCondition);
                this.parentMenuData = [];
            },
            roleHandleCurrentChange: function(val){
                this.roleSearchCondition.page = val;
                getRoleList(this,this.roleSearchCondition);
            },
            selectRoleCell: function(row){
                let tableData = this.roleTableData.records;
                for(let i=0; i<tableData.length; i++){
                    let item = tableData[i];
                    item["selected"] = false;
                }
                row["selected"] = true;
                this.roleTableData.selectRoleRow = row;
            },
            selectTableRow: function(row, column, event){
                if(column.no != 2){
                    this.selectRoleCell(row);

                    //获取菜单
                    let menuParam = {
                        roleId: row.roleId
                    }
                    getParentMenuByRole(this, menuParam);
                }
            },
            openRoleDialog: function(index, row){
                if(row == null){
                    //新增
                    this.roleDialogOption.title = "新增角色";
                    this.roleDialogOption.type = 0;
                }else{
                    //修改
                    this.roleDialogOption.title = "编辑角色";
                    this.roleDialogOption.type = 1;
                    this.roleDataForm.roleId = row.roleId;
                    this.roleDataForm.roleName = row.roleName;
                }
                this.roleDialogOption.show = true;
            },
            roleDialogBeforeClose: function(){
                roleDialogCloseTips(this);
            },
            roleDialogClose: function(){
                this.roleDataForm = {
                    roleId: null,
                    roleName: ""
                };
                this.$refs["roleFormRef"].clearValidate();
            }, 
            confirmRoleDialog: function(){
                const obj = this;
                this.$refs["roleFormRef"].validate(function(valid) {
                    if(valid){
                        if(obj.roleDialogOption.type == 0){
                            //新增
                            insertRole(obj, obj.roleDataForm);
                        }else{
                            //修改
                            updateRole(obj, obj.roleDataForm);
                        }
                    }else{
                        return false;
                    }
                });
            },
            roleDel: function(index, row){
                var obj = this;
                var confirmMessage = "是否删除当前选择的角色：" + row.roleName + "?";
                this.$confirm(confirmMessage).then(function(){
                    const param = {
                        roleId : row.roleId
                    };
                    deleteRole(obj, param);
                }).catch(function(){});
            },
            showRequestListDialog: function(index,row){
                if(!this.roleTableData.selectRoleRow){
                    ElMessage({
                        showClose: true,
                        message: "请先选择角色",
                        type: 'error'
                    });
                    return;
                }
                this.requestListDialogOption.title = row.menuName;
                this.requestListDialogOption.isShow = true;
                this.requestListDialogOption.selectMenu = row;
            },
            requestListDialogOpen: function(){
                getRequestList(this,this.requestListDialogOption.selectMenu);
            },
            requestListDialogClosed: function(){
                this.requestListDialogOption.tableData = [];
                this.requestListDialogOption.title = "";
                this.requestListDialogOption.selectMenu = null;
            },
            refreshReuqestDialog: function(){
                getRequestList(this,this.requestListDialogOption.selectMenu);
            },
            saveRoleRequest: function(row){
                row.loading = true;
                return new Promise((resolve, reject)=>{
                    saveRoleRequest(this, row, resolve, reject);
                });
            },
            saveRoleMenu: function(row){
                row.loading = true;
                return new Promise((resolve, reject)=>{
                    saveRoleMenu(this, row, resolve, reject);
                });
            }
        },
        created : function(){
            const menuId = [this.$route.query.menuId]
            const obj = this;
            new tool.getAuthorisedRequest(menuId, this.btOption, function(){
                getRoleList(obj,obj.roleSearchCondition);
            });
        },
        components : {
            TableSpan
        },
        watch: {
            "roleTableData.selectRoleRow"(newVal, oldVal){
                if(newVal == null){
                    this.menuTableData.records = [];
                }
            }
        }
    }

    /**
     * 获取角色信息列表
     * @param app
     * @param param
     */
    function getRoleList(app, param){
        //清空之前选择的角色信息
        app.roleTableData.selectRoleRow = null;

        const url = "/user/role/list";
        tool.formJsonRequest(url,param,null,function(data){
            if(data.code === "0000"){
                app.roleTableData.total = data.data.total;
                app.roleTableData.current = data.data.current;
                app.roleTableData.size = data.data.size;

                app.roleTableData.records = [];
                for(let i=0;i<data.data.records.length;i++){
                    let item = data.data.records[i];
                    item["selected"] = false;
                    app.roleTableData.records.push(item);
                }
            }else{
                ElMessage({
                    showClose: true,
                    message: data.message,
                    type: 'error'
                });
            }
        });
    }

    /**
     * 新增角色信息
     * @param app vue对象
     * @param param 操作的参数
     */
    function insertRole(app, param){
        const url = "/user/role/save";
        tool.formJsonRequest(url,param,null,function(data){
            if(data.code === "0000"){
                ElMessage({
                    showClose: true,
                    message: '角色保存成功',
                    type: 'success'
                });
                app.roleDialogOption.show = false;
                app.roleSearchCondition.page = 1;
                getRoleList(app,app.roleSearchCondition);
            }else{
                ElMessage({
                    showClose: true,
                    message: data.message,
                    type: 'error'
                });
            }
        });
    }

    /**
     * 更新角色信息
     * @param app vue对象
     * @param param 操作的参数
     */
    function updateRole(app,param){
        const url = "/user/role/update";
        tool.formJsonRequest(url,param,null,function(data){
            if(data.code === "0000"){
                ElMessage({
                    showClose: true,
                    message: '角色更新成功',
                    type: 'success'
                });
                app.roleDialogOption.show = false;
                getRoleList(app,app.roleSearchCondition);
            }else{
                ElMessage({
                    showClose: true,
                    message: data.message,
                    type: 'error'
                });
            }
        });
    }

    /**
     * 删除角色信息
     * @param app vue对象
     * @param param 操作的参数
     */
    function deleteRole(app,param){
        const url = "/user/role/delete";
        tool.formJsonRequest(url,param,null,function(data){
            if(data.code === "0000"){
                ElMessage({
                    showClose: true,
                    message: '角色删除成功',
                    type: 'success'
                });
                app.roleSearchCondition.page = 1;
                getRoleList(app,app.roleSearchCondition);
            }else{
                ElMessage({
                    showClose: true,
                    message: data.message,
                    type: 'error'
                });
            }
        });
    }

    /**
     * 弹窗关闭时的提示信息
     * @param app
     */
     function roleDialogCloseTips(app) {
        let confirmMessage = "";
        if(app.roleDialogOption.type == 0){
            confirmMessage = "是否放弃新增角色？";
        }else{
            confirmMessage = "是否放弃编辑角色？"
        }
        app.$confirm(confirmMessage).then(function(){
            app.roleDialogOption.show = false;
        }).catch(function(){

        });
    }


    /**-----------------        角色对应的菜单相关操作      --------------------*/

    /**
     * 根据角色的唯一标识获取菜单信息
     * @param app
     * @param param 查询条件 角色的唯一标识
     */
     function getParentMenuByRole(app,param){
        const url = "/user/role/menu/authMenuList";
        tool.formJsonRequest(url,param,null,function(data){
            if(data.code === "0000"){
                app.menuTableData.records = data.data;
                for(let i=0; i<app.menuTableData.records.length; i++){
                    let item = app.menuTableData.records[i];
                    if(item.icon){
                        item["showIcon"] = "<i class='" + item.icon + "' style='font-size: 20px'></i>";
                    }
                    item["loading"] = false;
                    if(item.children != null){
                        menuRecursion(item.children);
                    }
                }
            }else{
                ElMessage({
                    showClose: true,
                    message: data.message,
                    type: 'error'
                });
            }
        });
    }


    /**
     * 递归循环菜单列表
     * @param menuList 菜单列表
     */
    function menuRecursion(menuList) {
        for(let i=0; i<menuList.length; i++){
            let item = menuList[i];
            let childMenu = item.children;
            if(childMenu != null){
                menuRecursion(childMenu);
            }
            if(item.icon){
                item["showIcon"] = "<i class='" + item.icon + "' style='font-size: 20px'></i>";
            }
        }
    }

    /**
     * 获取页面对应的按钮及请求地址
     * @param app app对象
     * @param menuObject 获取数据的列表
     */
     function getRequestList(app,menuObject) {
        const option = {
            "roleId": app.roleTableData.selectRoleRow.roleId,
            "menuId": menuObject.menuId,
            "size": -1
        };
        const url = "/user/role/request/authRequestList";
        tool.formJsonRequest(url,option,function(){},function(data){
            if(data.code == "0000"){
                //清空数组
                app.requestListDialogOption.tableData = data.data;
                for(let i=0; i<app.requestListDialogOption.tableData.length; i++){
                    let item = app.requestListDialogOption.tableData[i];
                    item["loading"] = false;
                }
            }else{
                ElMessage({
                    showClose: true,
                    message: data.message,
                    type: 'error'
                });
            }
        });
    }

    /**
     * 更新角色对应的接口权限
     * @param app app对象
     * @param dataRow 请求的参数
     * @param resolve Promise 成功回调
     * @param reject Promise 失败回调
     */
    function saveRoleRequest(app, dataRow, resolve, reject) {
        let isAllow = "";
        if("0" === dataRow.isAllow){
            isAllow = "1";
        }else{
            isAllow = "0";
        }
        const param = {
            "roleId": app.roleTableData.selectRoleRow.roleId,
            "requestId": dataRow.requestId,
            "isAllow": isAllow
        }
        const url = "/user/role/request/saveOrUpdate/roleRequest";
        tool.formJsonRequest(url,param,
        function(){
            dataRow.loading = false;
            reject(false);
        },
        function(data){
            dataRow.loading = false;
            if(data.code == "0000"){
                resolve(true);
            }else{
                ElMessage({
                    showClose: true,
                    message: data.message,
                    type: 'error'
                });
                reject(false);
            }
        },false);
    }

    /**
     * 更新角色对应菜单的权限
     * @param app app对象
     * @param dataRow 请求的参数
     * @param resolve Promise 成功回调
     * @param reject Promise 失败回调
     */
    function saveRoleMenu(app, dataRow, resolve, reject){
        let isAllow = "";
        if("1" === dataRow.isAllow){
            isAllow = "1";
        }else{
            isAllow = "0";
        }
        const param = {
            "roleId": app.roleTableData.selectRoleRow.roleId,
            "menuId": dataRow.menuId,
            "delFlag": isAllow
        }
        const url = "/user/role/menu/saveOrUpdate/RoleMenu";
        tool.formJsonRequest(url,param,
        function(){
            dataRow.loading = false;
            reject(false);
        },
        function(data){
            dataRow.loading = false;
            if(data.code == "0000"){
                resolve(true);
            }else{
                ElMessage({
                    showClose: true,
                    message: data.message,
                    type: 'error'
                });
                reject(false);
            }
        },false);
    }
</script>

<style scoped>
    .role_span{
        display: flex;
        flex-direction: column;
        width: 100%;
        height: 100%;
        font-family: Microsoft YaHei,Heiti SC,tahoma,arial,Hiragino Sans GB,"\5B8B\4F53",sans-serif;
        flex-wrap : wrap;
        overflow-x: auto;
    }
    .role_span .role_left_span{
        width: 400px;
        height: 100%;
        border-right: 1px solid #EBEEF5;

    }
    .role_span .role_center_span{
        width: calc(100% - 460px);
        height: 100%;
        border-left: 1px solid #EBEEF5;
        border-right: 1px solid #EBEEF5;
    }
    .role_span .role_right_span{
        min-width: 200px;
        width: calc(100% - 420px);
        height: 100%;
        border-left: 1px solid #EBEEF5;
    }
    .role_span .angle_span{
        display: flex;
        align-items: center;
        justify-content: center;
        width : 38px;
        height: 100%;
        margin-left: 1px;
        margin-right: 1px;
        font-size: 28px;
        font-weight: 400;
        color: #909399;
    }
    .search_item_span{
        min-width: 80px;
        height: auto;
        margin-top: 5px;
        margin-left: 10px;
    }
    .role_icon_span{
        font-size: 18px;
    }
    .role_icon_selected{
        color: #409eff;
    }
    .role_icon_unselected{
        color: #666666;
    }
    .dialog_header{
        display: flex;
        flex-direction: row;
        align-items: center;
    }
    .dialog_header .dialog_header_icon{
        display: flex;
        flex-direction: row;
        align-items: center;
        margin-left: 6px;
        cursor: pointer;
    }

</style>